home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / cross / GBDK-2.0.lha / GBDK / lib / realloc.c < prev    next >
C/C++ Source or Header  |  1998-10-01  |  2KB  |  86 lines

  1. #include <sys/malloc.h>
  2. #include <stdlib.h>
  3. #include <types.h>
  4. #include <string.h>
  5.  
  6. void *realloc( void *current, UWORD size )
  7. {
  8.     /* First see if the following hunk is free */
  9.     UWORD nextSize;
  10.     pmmalloc_hunk thisHunk, newHunk, ptr;
  11.     void *newRegion;
  12.  
  13.     thisHunk = malloc_first;
  14.  
  15.     ptr = (void *)((UWORD)current - sizeof(mmalloc_hunk));
  16.  
  17.     if (size==0) {
  18.         free(current);
  19.         return NULL;
  20.     }
  21.     if (current==NULL) {
  22.         return malloc(size);
  23.     }
  24.         
  25.     while (thisHunk && (thisHunk->magic==MALLOC_MAGIC)) {
  26.         if (thisHunk == ptr) {
  27.             debug("realloc", "Found hunk");
  28.             if (thisHunk->size == size )
  29.                 return current;
  30.                 
  31.             if (thisHunk->size > size ) {
  32.                 if (thisHunk->size > size + sizeof( mmalloc_hunk )) {
  33.                     /* Shrink the hunk */
  34.                     newHunk = (pmmalloc_hunk)(size + sizeof( mmalloc_hunk )+(UWORD)thisHunk);
  35.                     newHunk->status = MALLOC_FREE;
  36.                     newHunk->size = thisHunk->size - size -sizeof( mmalloc_hunk );
  37.                     newHunk->magic = MALLOC_MAGIC;
  38.                     newHunk->next = thisHunk->next;
  39.  
  40.                     thisHunk->next = newHunk;
  41.                     thisHunk->size = size;
  42.                     return current;
  43.                 }
  44.                 else {    
  45.                     /* Cant shrink the hunk as there's not enough room to put a new hunk header */
  46.                     return current;
  47.                 }
  48.             }
  49.             if (thisHunk->next != NULL) {
  50.                 if (thisHunk->next->status == MALLOC_FREE) {
  51.                     /* Stand a much better change if we gc first */
  52.                     malloc_gc();
  53.                     nextSize = thisHunk->next->size;
  54.                     
  55.                     if ((nextSize + thisHunk->size + sizeof( mmalloc_hunk )) >= size ) {
  56.                         /* Next hunk + this is big enough to contain the new hunk */
  57.                         
  58.                         newHunk = (pmmalloc_hunk)(size + sizeof( mmalloc_hunk )+(UWORD)thisHunk);
  59.                         newHunk->next = thisHunk->next->next;
  60.                         newHunk->status = MALLOC_FREE;
  61.                         newHunk->size = thisHunk->size + nextSize - size -sizeof( mmalloc_hunk );
  62.                         newHunk->magic = MALLOC_MAGIC;
  63.  
  64.                         thisHunk->next = newHunk;
  65.                         thisHunk->size = size;
  66.                         return current;
  67.                     }
  68.                 }
  69.                 /* Oh well.  Allocate a new hunk then free this one */
  70.                 newRegion = malloc (size);
  71.                 if (newRegion) {
  72.                     memcpy( newRegion, current, thisHunk->size );
  73.                     free( current );
  74.                     return newRegion;
  75.                 }
  76.                 return NULL;    /* Couldnt do it */
  77.             }
  78.         }
  79.         thisHunk = thisHunk->next;
  80.     };
  81.  
  82.     debug("realloc", "No hunk found");
  83.     return NULL;
  84. }
  85.  
  86.